package com.xayy.core.antlr4.model;

import cn.kawins.base.utils.CollUtil;
import com.xayy.core.antlr4.exception.UnexpectedParamTypeException;
import lombok.Getter;

import java.util.List;

/**
 * visitor访问语法树每个节点的返回结果和自定义函数返回结果类 返回结果包含 四种类型 数值型（全部转为double）、字符串、布尔型，List,每次只可能返回四种类型中的一种
 *
 * @author dongxingli createTime 2020/9/24
 * @version V1.0
 */
@Getter
public class VisitorResult {

    private Object value;

    private VisitorResult() {

    }

    private VisitorResult(Object value) {
        if (value instanceof String || value instanceof Double || value instanceof Boolean || value instanceof List
            || value == null) {
            this.value = value;
        } else {
            throw new UnexpectedParamTypeException("不支持的参数类型" + value);
        }
    }

    public Boolean getBool() {
        if (isBoolean()) {
            return (Boolean)value;
        }
        throw new UnexpectedParamTypeException("非Boolean类型");
    }

    public Double getNumber() {
        if (isNumber()) {
            return (Double)value;
        }
        throw new UnexpectedParamTypeException("非Number类型");
    }

    public String getVarchar() {
        if (isVarchar()) {
            return (String)value;
        }
        throw new UnexpectedParamTypeException("非Varchar类型");
    }

    public List<Double> getList() {
        if (isList()) {
            return (List<Double>)value;
        }
        throw new UnexpectedParamTypeException("非List类型");
    }

    public static VisitorResult value(Object value) {
        return new VisitorResult(value);
    }

    /**
     * 返回NULL
     *
     * @return 结果类
     */
    public static VisitorResult nll() {
        return new VisitorResult();
    }

    /**
     * 返回结果是否数值型
     *
     * @return 是或否
     */
    public boolean isNumber() {
        return this.value instanceof Number;
    }

    /**
     * 返回结果是否字符串
     *
     * @return 是或否
     */
    public boolean isVarchar() {
        return this.value instanceof String;
    }

    /**
     * 返回结果是否布尔型
     *
     * @return 是或否
     */
    public boolean isBoolean() {
        return this.value instanceof Boolean;
    }

    /**
     * 返回结果是否List
     *
     * @return 是或否
     */
    public boolean isList() {
        return this.value instanceof List;
    }

    /**
     * 返回结果是否为null
     *
     * @return 是或否
     */
    public boolean isNull() {
        return value == null;
    }

    @Override
    public String toString() {
        if (isNumber()) {
            return Double.toString((Double)value);
        } else if (isVarchar()) {
            return (String)value;
        } else if (isBoolean()) {
            return Boolean.toString((Boolean)value);
        } else if (isList()) {
            List<Object> list = CollUtil.toList(value);
            return list.toString();
        } else {
            throw new UnexpectedParamTypeException("未知类型");
        }
    }
}
